package xyz.longicorn.driver.config;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import xyz.longicorn.driver.config.annotation.OperationLog;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 配置需要关注的点 - 切面
 */
@Aspect // 1
@Component
@Slf4j
public class AppLogConfig {

    // 2.配置切入点 -- 要关注(拦截)哪些方法
    // 主要使用了OperationLog注解的方法都要拦截
    @Pointcut("@annotation(xyz.longicorn.driver.config.annotation.OperationLog)")
    public void recordOpLogPointCut() {
    }

    //拦截xyz.longicorn.driver.controller包下所有类的所有方法
//    @Pointcut("execution(* xyz.longicorn.driver.controller..*.*(..))")
    //execution(<修饰符模式>？<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)
    // 如果匹配所有 用*代理所有部分
    public void opControllerLogPointCut() {
    }

    @Before("recordOpLogPointCut()")// 设置某个切入点(方法)执行时要增强的代码
    public void recordOpLog(JoinPoint joinPoint) { // joinPoint可以看成具体的方法
        // 从全局对象中拿到请求对象
        ServletRequestAttributes requestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) return;
        // 获取请求
        HttpServletRequest request = requestAttributes.getRequest();

        // 因为注解只能用于方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取到相应执行的方法
        Method m = signature.getMethod();
        // 通过method获取到当前注解
        final OperationLog op = m.getAnnotation(OperationLog.class);
        String value = op.value();


        log.info("用户开始访问了:" + request.getRequestURI()
                + "执行的方法是：" + m.getName()
                + "当前方法的注释为:" + value);
    }
}
